package cn.snowheart.template;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

/**
 * 封装算法的结构和固定的实现部分，比如此例中的删除文件、创建文件，以及各方法间的实现顺序
 * 各实现类根据业务场景的不同，实现不同的写文件方法
 * <p>
 * 搭配以Spring的这种依赖注入，具体算法实现类的声明和注入都在配置文件中做到
 * 算法的使用方和实现方之间，完全解耦
 *
 * @author liuwanxiang
 * @version 2019/07/08
 */
public abstract class MyFileWriter {

    public final void write(String fileName, Object content) {

        File file = new File(fileName);
        boolean appendMode = true;
        if (file.exists()) {
            if (ifDelete(fileName)) {
                file.delete();
                createFile(file);
                appendMode = false;
            }
        } else {
            createFile(file);
        }

        try (FileWriter fw = new FileWriter(file, appendMode)) {
            writeFile(fw, content);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            doSomeThing();
        }

    }

    /**
     * 一个创建文件的默认实现
     *
     * @param file
     */
    protected final void createFile(File file) {
        try {
            file.createNewFile();
            file.setWritable(true);
            file.setReadable(true);
            file.setExecutable(true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 如果旧文件已存在，是否要进行删除
     *
     * @param fileName 文件名称
     * @return true 删除 false 保留并追加
     */
    protected abstract boolean ifDelete(String fileName);

    /**
     * 写文件的具体方法
     *
     * @param fw      FileWriter
     * @param content 文件内容
     * @throws Exception 异常
     */
    protected abstract void writeFile(FileWriter fw, Object content) throws Exception;

    /**
     * 钩子方法
     */
    protected void doSomeThing() {
        // doNoThing...
    }

}
